Skip to content

Fix #2833: Fixes to harmonize #2843

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 10, 2017
Merged

Conversation

odersky
Copy link
Contributor

@odersky odersky commented Jul 10, 2017

We try to replace harmonize with something weaker that only applies to constants.

As a first step: make pattern matching typecheck more principled

When checking a pattern p against a selector s we should check
that p == s is typeable. So far we did this in a roundabout way
by calling harmonizeType and canCheckEquals directly. But that
is correct only if there are no user-defined definitions of ==.

The new algorithm for harmonize is described a new section of the language reference.

odersky added 4 commits July 10, 2017 09:33
When checking a pattern `p` against a selector `s` we should check
that `p == s` is typable. So far we did this in a roundabout way
by calling homogenizeType and canCheckEquals diretcly. But that
is correct only if there are no user-defined definitions of `==`.
We now widen a vararg parameter or alternative of
an If or Match only to another numeric value type
only if the original type is a constant type, and the
type can be widened without loss of precision (here
we deem it acceptable that Ints are widened to Floats,
but Longs can only be widened to Doubles).
After erasure, the rhs of an inline val like

    inline val n = 3

no longer has a constant type. Therefore, we need to disable
the check for it after erasure. Test case (discovered by
accident) in harmonize.scala.
Also, adapt the algorithm to the reference (i.e. convert
only if the resulting types all agree).
@odersky odersky changed the title Fix #2833: Fixes to harmonize [WIP] Fix #2833: Fixes to harmonize Jul 10, 2017
@odersky odersky requested a review from olafurpg July 10, 2017 10:07
title: Dropped: Weak Conformance
---

In some situations, Scala used a {\em weak conformance} relation when
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you can use latex code in our documentation. You should be able to write *weak conformance* instead which should be rendered as weak conformance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. That comes from switching context from writing a paper with LaTex...


__Examples:__

inline val b: Byte = 3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good if there was some explanation of how the rules differ between val and inline val.

Copy link
Contributor

@olafurpg olafurpg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the fix! A few comments on the docs.

inline val s: Short = 33
def f(): Int = b + s
List(b, s, 'a') : List[Int]
List(b, s, 'a', f()): List[Int]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be good to note here that the type is List[Int] because Int is the LUB, not because of the new rule.

List(n, c, d) // used to be: List[Double], now: List[AnyVal]

Here, it is less clear why the type should be widened to
`List[Double]`, a `List[AnyVal` seems to be an equally valid -- and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing closing bracket: List[AnyVal]


To simplify the underlying type theory, Dotty drops the notion of weak
conformance altogether. Instead, it provides more flexibility when
assigning a type to a constant expression. The rule is:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this rule have a name? Is it a new Dotty feature?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it so say that it is new. It does not have a name (yet).


- If a list of expressions `Es` appears as one of

- the elements of a vararg parameter, or
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens when it's not a vararg parameter list?

def add[T](a: T, b: T): List[T] = List(a, b)
add(1.0f, 1L) // Double?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, AnyVal.

List(b, s, 'a') : List[Int]
List(b, s, 'a', f()): List[Int]
List(1.0f, 'a', 0) : List[Float]
List(1.0f, 1L) : List[Double]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a 1: Int here to highlight the difference between f() and 1: Int?


__Examples:__

inline val b: Byte = 3
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if this is final instead of inline?

@odersky
Copy link
Contributor Author

odersky commented Jul 10, 2017

If I get am LGTM today we can still roll this in the release...

Copy link
Contributor

@olafurpg olafurpg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

There are cases where the behavior is different from 2.12

scala> List(1L, 1f)
res1: List[Float] = List(1.0, 1.0) // Dotty yields Double

We'll have to see how much this impacts code in the wild.

@odersky odersky merged commit 1c9552b into scala:master Jul 10, 2017
@allanrenucci allanrenucci deleted the fix-homogenize branch December 14, 2017 19:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants